﻿using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Highlighting;
using JHECIS.DataModel;
using JHECIS.DataModel.Interface;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using JhEngine.Helpers;
using JHECIS.InterfaceTool.Common;
using RestSharp;
using JHECIS.InterfaceToolDataService;
using Prism;
using Prism.Regions;
using Prism.Commands;
using System.Windows;

namespace JHECIS.InterfaceTool.ViewModel
{
    public class MainWindowViewModel : Prism.Mvvm.BindableBase, IActiveAware, IDisposable, INavigationAware
    {

        #region 构造函数

        public MainWindowViewModel()
        {
            ServerUrl = ConfigHelper.GetConfig("ServicesUrl");
            var client = new RestClient(ServerUrl)
            {
                Authenticator = new ApiAuthenticator()
            };
            service = new InterfaceToolService(client);

            ScriptConvertCommand = new DelegateCommand<object>(OnScriptConvert);
            FormatCommand = new DelegateCommand<object>(OnFormart);
            ClearResultCommand = new DelegateCommand<object>(OnClearResult);
            LoadInterfaceToolCommand = new DelegateCommand<object>(OnLoadInterfaceTool);
            SaveInterfaceToolCommand = new DelegateCommand<object>(OnSaveInterfaceTool);
            ScriptTypeCommand = new DelegateCommand<object>(OnScriptType);
            DeleteCommand = new DelegateCommand<object>(OnDelete);
            AddNewCommand = new DelegateCommand<object>(OnAdeNew);
            SearchCommand = new DelegateCommand<object>(OnSearch);

            using (var stream = typeof(MainWindowViewModel).Assembly.GetManifestResourceStream("JhEngine.HighLight.javascript.xshd"))
            {
                using (var reader = new System.Xml.XmlTextReader(stream))
                {
                    pythonHighlight = ICSharpCode.AvalonEdit.Highlighting.Xshd.HighlightingLoader.Load(reader, HighlightingManager.Instance);
                }
            }
            InitData();
        }

        event EventHandler IActiveAware.IsActiveChanged
        {
            add
            {
                throw new NotImplementedException();
            }

            remove
            {
                throw new NotImplementedException();
            }
        }
        #endregion

        #region 变量

        private ScriptContent _scriptContent = new ScriptContent();
        private IHighlightingDefinition javascriptHighlight;
        private IHighlightingDefinition pythonHighlight;
        private InterfaceToolService service;

        #endregion
        public class InterfaceTree : TreeViewItemBase
        {
            public string Name { get; set; }
        }
        #region 属性
        public string ServerUrl { get; set; }
        public List<string> InAutoComplete { get; set; }

        private InterfaceToolEntity _currInterfaceTool;

        public InterfaceToolEntity CurrInterfaceTool
        {
            get => _currInterfaceTool;
            set
            {
                _currInterfaceTool = value;
                RaisePropertyChanged(nameof(CurrInterfaceTool));
            }
        }

        public bool JavaScriptChecked
        {
            get
            {
                return CurrInterfaceTool != null && CurrInterfaceTool.SCRIPTTYPE == 0;
            }
            set
            {
                if (CurrInterfaceTool != null && value)
                {
                    CurrInterfaceTool.SCRIPTTYPE = 0;
                }
              
                RaisePropertyChanged(nameof(JavaScriptChecked));
            }
        }


        public DelegateCommand<object> ScriptConvertCommand { get; }
        public DelegateCommand<object> FormatCommand { get; }
        public DelegateCommand<object> ClearResultCommand { get; }
        public DelegateCommand<object> LoadInterfaceToolCommand { get; }
        public DelegateCommand<object> SaveInterfaceToolCommand { get; }
        public DelegateCommand<object> ScriptTypeCommand { get; }

        public DelegateCommand<object> DeleteCommand { get; }

        public DelegateCommand<object> AddNewCommand { get; }

        public DelegateCommand<object> SearchCommand { get; }
        public ScriptContent ScriptContent
        {
            get => _scriptContent;
            set
            {
                _scriptContent = value;
                RaisePropertyChanged(nameof(ScriptContent));
            }
        }

        //public string ConvertResult
        //{
        //    get => _convertResult;
        //    set
        //    {
        //        _convertResult = value;
        //        RaisePropertyChanged(nameof(ConvertResult));
        //    }
        //}

        public TextDocument ScriptCode
        {
            get => scriptCode;
            set
            {
                scriptCode = value;
                RaisePropertyChanged(nameof(ScriptCode));
            }
        }
        public TextDocument ConvertResult
        {
            get => convertResult;
            set
            {
                convertResult = value;
                RaisePropertyChanged(nameof(ConvertResult));
            }
        }
        public TextDocument InJson
        {
            get => inJson;
            set
            {
                inJson = value;
                RaisePropertyChanged(nameof(InJson));
            }
        }
        public TextDocument OutJson
        {
            get => outJson;
            set
            {
                outJson = value;
                RaisePropertyChanged(nameof(OutJson));
            }
        }
        public IHighlightingDefinition HighlightingDefinition
        {
            get
            {
                return _HighlightingDefinition;
            }

            set
            {
                if (_HighlightingDefinition != value)
                {
                    _HighlightingDefinition = value;
                    RaisePropertyChanged(nameof(HighlightingDefinition));
                }
            }
        }
        private Dictionary<InterfaceTree, List<InterfaceToolEntity>> _interfaceToolGroup;
        private TextDocument convertResult;
        private TextDocument scriptCode;
        private TextDocument outJson;
        private TextDocument inJson;
        private IHighlightingDefinition _HighlightingDefinition;
        private List<InterfaceToolEntity> allInterfaceTool;
        public Dictionary<InterfaceTree, List<InterfaceToolEntity>> InterfaceToolGroup
        {
            get => _interfaceToolGroup;
            set
            {
                _interfaceToolGroup = value;
                RaisePropertyChanged(nameof(InterfaceToolGroup));
            }
        }

        bool IActiveAware.IsActive { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }


        #endregion

        #region 方法

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            InitData();
        }

        private void InitData(List<InterfaceToolEntity> interfaceTools = null)
        {
            try
            {

                var list = interfaceTools;
                if (list == null)
                {
                    list = allInterfaceTool = service.GetInterfaceTool();
                }
                InterfaceToolGroup = list.FindAll(a => !string.IsNullOrEmpty(a.CLASSNAME) && a.INVALIDFLAG.HasValue && a.INVALIDFLAG.Value == 0)
                    .GroupBy(a => a.CLASSNAME).OrderBy(a => a.Key)
                    .ToDictionary(a => new InterfaceTree { Name = a.Key }, a => a.ToList());
                CurrInterfaceTool = new InterfaceToolEntity();
                InJson = new TextDocument();
                OutJson = new TextDocument();
                ConvertResult = new TextDocument();
                ScriptCode = new TextDocument();
            }
            catch (Exception ex)
            {
                LogHelper.GetLogHelper().Error(ex);
            }
        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
        }


        private void OnScriptConvert(object obj)
        {
            ScriptContent.Data = InJson.Text;
            ScriptContent.JavaScriptCode = ScriptCode.Text;
            ScriptContent.FunctionName = CurrInterfaceTool.FUNCTIONNAME;
            ScriptContent.ScriptType = CurrInterfaceTool.SCRIPTTYPE;

            if (!string.IsNullOrEmpty(ScriptContent.Error))
            {

                return;
            }

            try
            {
                ConvertResult.Text = service.Convert(ScriptContent);
                //ConvertResult.Text = Newtonsoft.Json.Linq.JToken.Parse(ConvertResult.Text).ToString();
            }
            catch (Exception ex)
            {
                LogHelper.GetLogHelper().Error(ex);

            }
        }

        private void OnFormart(object obj)
        {
            try
            {
                if (JavaScriptChecked)
                {
                    ScriptCode.Text = FormatHelper.FormatJsCode(ScriptCode.Text);
                }
                if (!string.IsNullOrEmpty(InJson.Text))
                {
                    InJson.Text = JToken.Parse(InJson.Text).ToString();
                }
                if (!string.IsNullOrEmpty(OutJson.Text))
                {
                    OutJson.Text = JToken.Parse(OutJson.Text).ToString();
                }
                if (!string.IsNullOrEmpty(ConvertResult.Text))
                {
                    ConvertResult.Text = JToken.Parse(ConvertResult.Text).ToString();
                }
            }
            catch (Exception ex)
            {
                LogHelper.GetLogHelper().Error(ex);
                //System.Windows.MessageBox.Show(ex.Message);
            }
        }

        private void OnClearResult(object obj)
        {
            ConvertResult.Text = string.Empty;
        }

        private void AddInAutoComplete(JObject jb)
        {
            jb.Properties().ToList().ForEach(a =>
            {
                InAutoComplete.Add(a.Name);
                if (a.Value is JObject jb1)
                {
                    AddInAutoComplete(jb1);
                }
                else if (a.Value is JArray jarray)
                {
                    if (jarray.First is JObject job1)
                    {
                        AddInAutoComplete(job1);
                    }
                }
            });
        }

        private void OnLoadInterfaceTool(object obj)
        {
            try
            {
                if (obj is InterfaceToolEntity interfaceTool)
                {
                    CurrInterfaceTool = interfaceTool;
                    if (string.IsNullOrEmpty(CurrInterfaceTool.JAVASCRIPTCODE) && !string.IsNullOrEmpty(CurrInterfaceTool.ID))
                    {
                        CurrInterfaceTool = service.GetInterfaceToolByCode(CurrInterfaceTool.INTERFACECODE);
                    }
                    //null赋值给text报错导致js脚本内容加载不出来的bug修复
                    InJson.Text = CurrInterfaceTool?.INJSON ?? string.Empty;
                    OutJson.Text = CurrInterfaceTool?.OUTJSON ?? string.Empty;
                    ScriptCode.Text = CurrInterfaceTool?.JAVASCRIPTCODE ?? string.Empty;

                    var jo = JObject.Parse(InJson.Text);
                    InAutoComplete = new List<string>();
                    AddInAutoComplete(jo);

                    RaisePropertyChanged(nameof(JavaScriptChecked));
                  
                    OnScriptType(CurrInterfaceTool.SCRIPTTYPE.ToString());
                }
                else if (obj is KeyValuePair<InterfaceTree, List<InterfaceToolEntity>> keyvalue)
                {
                    keyvalue.Key.IsExpanded = !keyvalue.Key.IsExpanded;
                }
            }
            catch (Exception ex)
            {
                LogHelper.GetLogHelper().Error(ex);
            }
        }

        private void OnSaveInterfaceTool(object obj)
        {
            CurrInterfaceTool.JAVASCRIPTCODE = ScriptCode.Text;
            CurrInterfaceTool.INJSON = InJson.Text;
            CurrInterfaceTool.OUTJSON = OutJson.Text;
            CurrInterfaceTool.UPDATEDATE = DateTime.Now;
            CurrInterfaceTool.UPDATEUSER = "";

            if (SaveInterfaceTool())
            {
                System.Windows.MessageBox.Show($"保存【{CurrInterfaceTool.INTERFACENAME}】接口数据成功！");
                if (string.IsNullOrEmpty(CurrInterfaceTool.ID))
                {
                    InitData();
                }
            }
        }

        private void OnScriptType(object obj)
        {
            if (obj is string str)
            {
                switch (str)
                {
                    case "1":
                        HighlightingDefinition = javascriptHighlight;
                        break;
                    default:
                        HighlightingDefinition = pythonHighlight;
                        break;
                }
            }
        }
        private void OnSearch(object obj)
        {
            if (obj is string txtSearch)
            {
                if (allInterfaceTool != null)
                {
                    var upperSearch = txtSearch.ToUpper();
                    var list = allInterfaceTool.FindAll(Match);
                    InitData(list);

                    bool Match(InterfaceToolEntity a)
                    {
                        if (txtSearch.IsNullOrEmpty())
                        {
                            return true;
                        }
                        return a.INTERFACENAME.SafeContains(txtSearch) || PinYinConverter.GetChineseSpell(a.INTERFACENAME).SafeContains(upperSearch) || a.INTERFACECODE.SafeContains(txtSearch);
                    }
                }
            }
        }
        private void OnAdeNew(object obj)
        {
            CurrInterfaceTool = new InterfaceToolEntity
            {
                INJSON = string.Empty,
                OUTJSON = string.Empty,
                JAVASCRIPTCODE = string.Empty
            };

            OnLoadInterfaceTool(CurrInterfaceTool);
        }

        private void OnDelete(object obj)
        {
            if (string.IsNullOrEmpty(CurrInterfaceTool.ID))
            {
                return;
            }
            if (MessageBox.Show($"确定删除【{CurrInterfaceTool.INTERFACENAME}】接口吗？", "系统提示", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK)//询问
            {
                CurrInterfaceTool.ISDELETE = 1;
                if (SaveInterfaceTool())
                {
                    InitData();
                }
            }

        }
        private bool SaveInterfaceTool()
        {
            if (CurrInterfaceTool.ISDELETE != 1 && !string.IsNullOrEmpty(CurrInterfaceTool.Error))
            {
                return false;
            }
            var result = service.SaveInTerfaceTool(new List<InterfaceToolEntity> { CurrInterfaceTool });
            if (string.IsNullOrEmpty(result.msg) && result.data != null)
            {
                if (result.data.Result)
                {
                    return true;
                }
                System.Windows.MessageBox.Show(result.data.ErrMsg);
                return false;
            }
            if (!string.IsNullOrEmpty(result.msg))
            {
                System.Windows.MessageBox.Show(result.msg);
                return false;
            }
            return false;
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }
        #endregion
    }
}